/*
 * Copyright 2009 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package simple.runtime.components.impl.android;

import java.io.IOException;

import android.graphics.drawable.Drawable;
import android.view.View;
import simple.runtime.日志;
import simple.runtime.components.可视组件;
import simple.runtime.components.布局;
import simple.runtime.components.组件容器;
import simple.runtime.components.impl.组件Impl;
import simple.runtime.components.impl.android.util.ImageUtil;
import simple.runtime.components.impl.android.util.ViewUtil;
import simple.runtime.errors.文件未存在错误;
import simple.runtime.errors.索引超出界限错误;

/**
 * 具有Android视图的所有组件的基础基类。
 *
 * @author Herbert Czymontek
 */
public abstract class 视图组件 extends 组件Impl implements 可视组件 {
  /*
  android.view.View：
  https://developer.android.google.cn/reference/android/view/View
  */

  // 视图
  private final View view;

  // 属性支持
  private int backgroundColor;
  private String backgroundImage;
  private int justification;
  private int column;
  private int row;

  /**
   * 创建新的安卓视图组件。
   * 
   * @param container  将容纳组件的容器（不得为{@code null}，因为非可见组件必须是窗口）
   */
  protected 视图组件(组件容器 container) {
    super(container);
    // 预先设置，行和列属性会检验如果2个属性都设置了将会添加到布局中
    column = 布局_无_列;
    row = 布局_无_行;

    // 初始化并将组件添加到其容器中
    view = createView();
    
    // 面板创建视图将返回空，所以这里的判断下
    if (view != null) {
      // 给视图分配标识
      ViewUtil.allocationId(view);
      getComponentContainer().addComponent(this);
    }
  }

  /**
   * 创建并初始化基础安卓视图。
   * 
   * <p>由于该方法是由组件构造函数间接调用的，
   * 所以实现者不应该假设关于实例的状态，
   * 并且不应读取任何非静态字段。
   */
  protected abstract View createView();

  /**
   * 返回用户界面中显示的{@link View}。
   * 
   * @return  视图
   */
  public View getView() {
    return view;
  }

  @Override
  public void 销毁() {
    // 调用下父类的销毁方法
    super.销毁();
    
    // 将视图从父级中移除
    ViewUtil.removeView(getView());
  }

  // 基础

  @Override
  public int 标识() {
    return ViewUtil.allocationId(getView());
  }

  @Override
  public void 标识(int id) {
    ViewUtil.setId(getView(), id);
  }

  @Override
  public boolean 可视() {
    return ViewUtil.isVisible(getView());
  }
  
  @Override
  public void 可视(boolean visible) {
    ViewUtil.setVisible(getView(), visible);
  }
  
  @Override
  public int 宽度() {
    return ViewUtil.getWidth(getView());
  }

  @Override
  public void 宽度(int width) {
    ViewUtil.setWidth(getView(), width);
  }

  @Override
  public int 高度() {
    return ViewUtil.getHeight(getView());
  }

  @Override
  public void 高度(int height) {
    ViewUtil.setHeight(getView(), height);
  }

  // 背景

  @Override
  public int 背景颜色() {
    return backgroundColor;
  }

  @Override
  public void 背景颜色(int color) {
    backgroundColor = color;
    ViewUtil.setBackgroundColor(getView(), color);
  }

  @Override
  public String 背景图片() {
    return backgroundImage;
  }

  @Override
  public void 背景图片(String image) {
    backgroundImage = image;
    try {
      Drawable drawable = ImageUtil.getDrawable(image);
      if (drawable != null) {
        ViewUtil.setBackgroundDrawable(getView(), drawable);
      }
    } catch (IOException e) {
      throw new 文件未存在错误(image);
    }
  }

  // 填充

  @Override
  public int 左填充() {
    return ViewUtil.getPaddingLeft(getView());
  }

  @Override
  public void 左填充(int leftPadding) {
    ViewUtil.setPaddingLeft(getView(), leftPadding);
  }

  @Override
  public int 顶填充() {
    return ViewUtil.getPaddingTop(getView());
  }

  @Override
  public void 顶填充(int topPadding) {
    ViewUtil.setPaddingTop(getView(), topPadding);
  }

  @Override
  public int 右填充() {
    return ViewUtil.getPaddingRight(getView());
  }

  @Override
  public void 右填充(int rightPadding) {
    ViewUtil.setPaddingRight(getView(), rightPadding);
  }

  @Override
  public int 底填充() {
    return ViewUtil.getPaddingBottom(getView());
  }

  @Override
  public void 底填充(int bottomPadding) {
    ViewUtil.setPaddingBottom(getView(), bottomPadding);
  }

  @Override
  public void 置填充(int leftPadding, int topPadding, int rightPadding, int bottomPadding) {
    ViewUtil.setPadding(getView(), leftPadding, topPadding, rightPadding, bottomPadding);
  }

  // 边距，该布局参数支持所有布局

  @Override
  public int 左边距() {
    return ViewUtil.getMarginLeft(getView());
  }

  @Override
  public void 左边距(int leftMargin) {
    ViewUtil.setMarginLeft(getView(), leftMargin);
  }

  @Override
  public int 顶边距() {
    return ViewUtil.getMarginTop(getView());
  }

  @Override
  public void 顶边距(int topMargin) {
    ViewUtil.setMarginTop(getView(), topMargin);
  }

  @Override
  public int 右边距() {
    return ViewUtil.getMarginRight(getView());
  }

  @Override
  public void 右边距(int rightMargin) {
    ViewUtil.setMarginRight(getView(), rightMargin);
  }

  @Override
  public int 底边距() {
    return ViewUtil.getMarginBottom(getView());
  }

  @Override
  public void 底边距(int bottomMargin) {
    ViewUtil.setMarginBottom(getView(), bottomMargin);
  }

  @Override
  public void 置边距(int leftMargin, int topMargin, int rightMargin, int bottomMargin) {
    ViewUtil.setMargin(getView(), leftMargin, topMargin, rightMargin, bottomMargin);
  }

  // 对齐，该布局参数仅支持：线性布局、表格布局、单帧布局

  @Override
  public int 对齐() {
    布局 layout = getComponentContainer().getLayout();
    if (layout instanceof 线性布局Impl || layout instanceof 表格布局Impl ||
        layout instanceof 单帧布局Impl) {
      return justification;
    } else {
      日志.输出警告(日志.MODULE_NAME_RTL,
          "[" + hashCode() + "/可视组件.对齐] 该组件无对齐布局参数，获取对齐失败");
    }
    return justification;
  }

  @Override
  public void 对齐(int justification) {
    布局 layout = getComponentContainer().getLayout();
    if (layout instanceof 线性布局Impl) {
      this.justification = justification;
      ((线性布局Impl) layout).setComponentJustification(this, justification);
    } else if (layout instanceof 单帧布局Impl) {
      this.justification = justification;
      ((单帧布局Impl) layout).setComponentJustification(this, justification);
    } else if (layout instanceof 表格布局Impl) {
      this.justification = justification;
      ((表格布局Impl) layout).setComponentJustification(this, justification);
    } else {
      日志.输出警告(日志.MODULE_NAME_RTL,
          "[" + hashCode() + "/可视组件.对齐] 该组件无对齐布局参数，设置对齐失败；对齐=" + justification);
    }
  }

  // 权重，该布局参数仅支持：线程布局

  @Override
  public float 权重() {
    布局 layout = getComponentContainer().getLayout();
    if (layout instanceof 线性布局Impl) {
      return ((线性布局Impl) layout).getComponentWeight(this);
    } else {
      日志.输出警告(日志.MODULE_NAME_RTL,
          "[" + hashCode() + "/可视组件.权重] 该组件无权重布局参数，获取权重失败");
    }
    return 0;
  }

  @Override
  public void 权重(float weight) {
    布局 layout = getComponentContainer().getLayout();
    if (layout instanceof 线性布局Impl) {
      ((线性布局Impl) layout).setComponentWeight(this, weight);
    } else {
      日志.输出警告(日志.MODULE_NAME_RTL,
          "[" + hashCode() + "/可视组件.权重] 该组件无权重布局参数，设置权重失败；权重=" + weight);
    }
  }
  
  // 行和列，该布局参数仅支持：表格布局

  @Override
  public int 行() {
    return row;
  }

  @Override
  public void 行(int newRow) {
    if (row != 布局_无_行) {
      throw new 索引超出界限错误();
    }

    row = newRow;
    if (column != 布局_无_列) {
      布局 layout = getComponentContainer().getLayout();
      if (layout instanceof 表格布局Impl) {
        ((表格布局Impl) layout).placeComponent(this);
      }
    }
  }

  @Override
  public int 列() {
    return column;
  }

  @Override
  public void 列(int newColumn) {
    if (column != 布局_无_列) {
      throw new 索引超出界限错误();
    }

    column = newColumn;

    if (row != 布局_无_行) {
      布局 layout = getComponentContainer().getLayout();
      if (layout instanceof 表格布局Impl) {
        ((表格布局Impl) layout).placeComponent(this);
      }
    }
  }

}
